﻿using System.Configuration;
using System.Diagnostics;
using System.Globalization;
using System.Web.Mvc;
using TSharp.Core.Util;

namespace TSharp.Core.Mvc.Web.Filters
{
    /// <summary>
    ///     执行时间ActionFilter
    ///     <para>2010/8/4</para>
    ///     <para>TANGJINGBO</para>
    ///     <para>tangjingbo</para>
    /// </summary>
    public class ExecutionTimingActionFilterAttribute : ActionFilterAttribute
    {
        /// <summary>
        /// </summary>
        public static string ConfigKey_TimingEnabled = "TimingEnabled";

        /// <summary>
        /// </summary>
        public static string ViewDataKey_ExecutionTime = "ExecutionTime";

        /// <summary>
        /// </summary>
        public static string ViewDataKey_ResultTime = "ResultTime";

        /// <summary>
        ///     执行时间ActionFilter
        /// </summary>
        public static readonly IActionFilter Instance = new ExecutionTimingActionFilterAttribute();

        private readonly bool timingEnabled = ConfigurationManager.AppSettings[ConfigKey_TimingEnabled].ToBoolean();
        private Stopwatch timer;

        /// <summary>
        ///     在执行操作方法之前由 MVC 框架调用。
        /// </summary>
        /// <param name="filterContext">筛选器上下文。</param>
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
            if (timingEnabled)
            {
                timer = new Stopwatch();
                timer.Start();
            }
        }

        /// <summary>
        ///     在执行操作方法后由 MVC 框架调用。
        /// </summary>
        /// <param name="filterContext">筛选器上下文。</param>
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            base.OnActionExecuted(filterContext);
            if (timingEnabled)
            {
                timer.Stop();
                Trace.WriteLine(string.Format(CultureInfo.InvariantCulture, "Action execution time: {0}ms",
                                              timer.ElapsedMilliseconds));
                if (filterContext.Result is ViewResult)
                {
                    ((ViewResult) filterContext.Result).ViewData[ViewDataKey_ExecutionTime] = timer.ElapsedMilliseconds;
                }
            }
        }
    }
}